package com.tq.framework.core;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * 单例管理器
 *
 * @author TqCoder
 * @since 2.0.0
 */
public class SingletonManager {
    /**
     * 存储单例实例的 Map，Key 为 Class 类型，Value 为实例对象
     */
    private final static Map<Class<?>, Object> BEAN_MAP = new HashMap<>();

    /**
     * 存储实例化方法的 Map，Key 为 Class 类型，Value 为创建函数
     */
    private final static Map<Class<?>, Function<Class<?>, ?>> FUNC_MAP = new HashMap<>();

    private SingletonManager() {}

    /**
     * 获取单例实例
     *
     * @param clazz 单例的 Class 类型
     * @param <T> 单例的类型
     * @return 单例实例
     */
    @SuppressWarnings("unchecked")
    public static synchronized <T> T getInstance(Class<T> clazz) {
        // 如果实例不存在，尝试创建并存入 BEAN_MAP
        return (T) BEAN_MAP.computeIfAbsent(clazz, cls -> {
            // 如果 FUNC_MAP 中存在创建函数，则使用创建函数生成实例
            if (FUNC_MAP.containsKey(cls)) {
                return FUNC_MAP.get(cls).apply(cls);
            }
            // 默认通过反射调用无参构造方法创建实例
            try {
                return cls.getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                throw new RuntimeException("Failed to create instance for class: " + cls.getName(), e);
            }
        });
    }

    /**
     * 注册一个自定义创建函数
     *
     * @param clazz 单例的 Class 类型
     * @param creator 创建函数
     * @param <T> 单例的类型
     */
    public static synchronized <T> void registerFunction(Class<T> clazz, Function<Class<?>, T> creator) {
        FUNC_MAP.put(clazz, creator);
    }

    /**
     * 手动注册单例实例
     *
     * @param clazz 单例的 Class 类型
     * @param instance 单例实例
     * @param <T> 单例的类型
     */
    public static synchronized <T> void registerInstance(Class<T> clazz, T instance) {
        BEAN_MAP.put(clazz, instance);
    }

    /**
     * 清除单例实例
     *
     * @param clazz 单例的 Class 类型
     */
    public static synchronized void removeInstance(Class<?> clazz) {
        BEAN_MAP.remove(clazz);
    }
}
